package com.cetcs.kmga.dataManager.service.impl.dataManager;

import com.cetcs.kmga.common.DateUtil;
import com.cetcs.kmga.dataManager.dao.mybatis.FeatureCodeMapper;
import com.cetcs.kmga.dataManager.dao.mybatis.LogQueryMapper;
import com.cetcs.kmga.dataManager.dao.mybatis.ResourceStatMapper;
import com.cetcs.kmga.dataManager.entity.dataManager.ResourceFlowCom;
import com.cetcs.kmga.dataManager.entity.dataManager.vo.ResourceRiskEventVo;
import com.cetcs.kmga.dataManager.entity.device.vo.KeyAndValueVo;
import com.cetcs.kmga.dataManager.entity.global.AlarmCode;
import com.cetcs.kmga.dataManager.entity.global.CodeAndValue;
import com.cetcs.kmga.dataManager.global.ResLogType;
import com.cetcs.kmga.dataManager.service.dataManager.ResourceStatService;
import com.cetcs.kmga.dataManager.util.NumConversion;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 资源概览实现层
 *
 * @author xutao
 * @version V1.0 创建时间：2017-10-25 11:45
 *          Copyright 2017 by CETC
 */
@Service
public class ResourceStatServiceImpl implements ResourceStatService {

    @Autowired
    private ResourceStatMapper resourceStatMapper;

    @Autowired
    private FeatureCodeMapper featureCodeMapper;

    /**
     * 统计资源当天的运行总量情况
     * 先从数据库中获取统计数据
     * 第一行为资源数据
     * 第二、三行为流入与流出数据
     * 第四行为风险事件数据
     *
     * @return
     */
    @Override
    public Map<String, Object> statResourceCurrentDayRunTimeTotal() {

        List<CodeAndValue> codeAndValues = resourceStatMapper.statResourceCurrentDayRunTimeTotal( );
        String sourceNum = "0";
        String dataNumOut = "0条";
        String dataNumIn = "0条";
        String riskNum = "0件";
        String riskTi = "0";//风险事件指数
        if (codeAndValues != null && codeAndValues.size( ) == 4) {
            //填充数据源数量
            if (codeAndValues.get(0) != null && StringUtils.isNotBlank(codeAndValues.get(0).getCode( ))) {
                sourceNum = codeAndValues.get(0).getCode( );
            }
            //填充流量读出
            long outNum = 0;
            if (codeAndValues.get(1) != null && StringUtils.isNotBlank(codeAndValues.get(1).getCode( ))) {
                outNum += Long.parseLong(codeAndValues.get(1).getCode( ));
            }
            if (codeAndValues.get(2) != null && StringUtils.isNotBlank(codeAndValues.get(2).getCode( ))) {
                outNum += Long.parseLong(codeAndValues.get(2).getCode( ));
            }
            dataNumOut = NumConversion.conversionNumUnit(outNum) + "条";
            long inNum = 0;
            if (codeAndValues.get(1) != null && StringUtils.isNotBlank(codeAndValues.get(1).getValue( ))) {
                inNum += Long.parseLong(codeAndValues.get(1).getValue( ));
            }
            if (codeAndValues.get(2) != null && StringUtils.isNotBlank(codeAndValues.get(2).getValue( ))) {
                inNum += Long.parseLong(codeAndValues.get(2).getValue( ));
            }
            dataNumIn = NumConversion.conversionNumUnit(inNum) + "条";
            //风险事件
            if (codeAndValues.get(3) != null && StringUtils.isNotBlank(codeAndValues.get(3).getCode( ))) {
                riskNum = NumConversion.conversionNumStrUnit(codeAndValues.get(3).getCode( )) + "件";
            }
        }
        //开始计算指数
        List<CodeAndValue> riskIndexList = resourceStatMapper.statResourceRiskIndexList( );
        List<CodeAndValue> weightIndexList = resourceStatMapper.statResourceWeights( );
        riskIndexList.forEach(p -> {
            List<CodeAndValue> singleWeight = weightIndexList.stream( ).filter(k -> p.getCode( ).equals(k.getCode( ))).collect(Collectors.toList( ));
            float wh = 0;
            if (singleWeight != null && singleWeight.size( ) > 0) {
                wh = Float.parseFloat(singleWeight.get(0).getValue( ));
            }
            float val = Float.parseFloat(p.getValue( ));
            float inVal = val * wh;

            p.setValue(String.valueOf(inVal));
        });
        Double totalIndVal = riskIndexList.stream( ).mapToDouble(p -> Double.parseDouble(p.getValue( ))).sum( );

        DecimalFormat df = new DecimalFormat("#0.00");
        if (totalIndVal == 0) {
            riskTi = "100";
        } else {
            totalIndVal = 100 - totalIndVal;
            riskTi = df.format(totalIndVal);
        }
        Map<String, Object> dataRet = new HashMap<>( );
        String[] dataNumArr = {dataNumOut, dataNumIn};
        dataRet.put("id", "1");
        dataRet.put("sourceNum", sourceNum);
        dataRet.put("riskNum", riskNum);
        dataRet.put("value", riskTi);
        dataRet.put("dataNum", dataNumArr);
        return dataRet;
    }

    /**
     * 统计资源当天的运行详情
     * 首先从数据库中取出所有资源以及需要统计的分析结果，然后组装数据
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> statResourceCurrentDayRunTimeDetailGroupByResrcId() {

        //取出所有的资源
        List<AlarmCode> resources = featureCodeMapper.findAllResourceCodes( );
        //取出所有的 当天的资源流量
        List<ResourceFlowCom> currentFlowComList = resourceStatMapper.statCurrentDayResourceFlowGroupByResrcId( );
        //取出所有的 统计最近三十天的流量总量
        List<ResourceFlowCom> thirtyDayFlowComList = resourceStatMapper.statRecentlyThirtyDayResourceFlowGroupByResrcId( );
        //取出所有的 统计当天的事件发生量
        List<ResourceFlowCom> currentRiskList = resourceStatMapper.statCurrentDayRiskEvtNumGroupByResrcId( );
        List<CodeAndValue> riskIndexList = resourceStatMapper.statResourceRiskIndexList( );
        DecimalFormat df = new DecimalFormat("#0.00");
        List<Map<String, Object>> ret = resources.stream( ).map(p -> {
            Map<String, Object> resourceStat = new HashMap<>( );
            String resId = p.getCode( );
            resourceStat.put("id", resId);
            String resType = ResLogType.getResLogType(p.getTypeId( )).toString( );
            resourceStat.put("type", resType);
            resourceStat.put("libraryName", p.getValue( ));
            List<CodeAndValue> singleIndexList = riskIndexList.stream( ).filter(k -> resId.equals(k.getCode( ))).collect(Collectors.toList( ));
            String indVal = "0";
            if (singleIndexList != null && singleIndexList.size( ) > 0) {
                indVal = singleIndexList.get(0).getValue( );
                if (!"0".equals(indVal)) {
                    double safeIndex = 100 - Double.parseDouble(indVal);
                    if(safeIndex==0){
                        indVal = "0";
                    }else {
                        indVal = df.format(safeIndex);
                    }
                } else {
                    indVal = "100";
                }
            }else {
                indVal = "100";
            }
            //指数
            resourceStat.put("deNum", indVal);
            //平均数与流量趋势
            List<Map<String, Object>> flowList = countResourceFlow(p.getCode( ), currentFlowComList, thirtyDayFlowComList);
            resourceStat.put("flow", flowList);
            //计算风险等级
            List<ResourceFlowCom> singleRiskList = currentRiskList.stream( ).filter(k -> resId.equals(k.getResrcId( ))).collect(Collectors.toList( ));
            long top = 0;
            long mid = 0;
            long small = 0;
            if (singleRiskList != null && singleRiskList.size( ) > 0) {
                //取出高等级
                if (StringUtils.isNotBlank(singleRiskList.get(0).getOutFlow( ))) {
                    top = Long.parseLong(singleRiskList.get(0).getOutFlow( ));
                }
                //取出中等级
                if (StringUtils.isNotBlank(singleRiskList.get(0).getInFlow( ))) {
                    mid = Long.parseLong(singleRiskList.get(0).getInFlow( ));
                }
                //取出低等级
                if (StringUtils.isNotBlank(singleRiskList.get(0).getResrcName( ))) {
                    small = Long.parseLong(singleRiskList.get(0).getResrcName( ));
                }
            }
            List<Long> levelArr = Lists.newArrayList( );
            levelArr.add(top);
            levelArr.add(mid);
            levelArr.add(small);
            resourceStat.put("rank", levelArr);
            List<ResourceFlowCom> ipFlowList = currentFlowComList.stream( ).filter(k -> resId.equals(k.getResrcId( ))).collect(Collectors.toList( ));
            String ipNum = "0";
            if (ipFlowList != null && ipFlowList.size( ) > 0) {
                ipNum = ipFlowList.get(0).getIpNum( );
            }
            resourceStat.put("ip", ipNum);
            return resourceStat;
        }).collect(Collectors.toList( ));
        return ret;
    }

    /**
     * 计算某个资源平均数与流量趋势
     *
     * @param resrcId              资源的ID
     * @param currentFlowComList   当天流量
     * @param thirtyDayFlowComList 三十天的总量
     * @return
     */
    private List<Map<String, Object>> countResourceFlow(String resrcId, List<ResourceFlowCom> currentFlowComList, List<ResourceFlowCom> thirtyDayFlowComList) {

        //当天的读取量
        long cOut = 0;
        //当天输入量
        long cIn = 0;
        List<ResourceFlowCom> currList = currentFlowComList.stream( ).filter(p -> resrcId.equals(p.getResrcId( ))).collect(Collectors.toList( ));
        //取出资源的流量
        if (currList != null && currList.size( ) > 0) {
            cOut = Long.parseLong(currList.get(0).getOutFlow( ));
            cIn = Long.parseLong(currList.get(0).getInFlow( ));
        }
        //读取量方向
        int dOut = 1;
        //输入量方向
        int dIn = 1;
        List<ResourceFlowCom> dayList = thirtyDayFlowComList.stream( ).filter(p -> resrcId.equals(p.getResrcId( ))).collect(Collectors.toList( ));
        //取出资源的流量
        if (dayList != null && dayList.size( ) > 0) {
            //三十天的读取量
            long tOut = Long.parseLong(dayList.get(0).getOutFlow( ));
            dOut = countCurrentFlowTrend(cOut, tOut);
            //三十天的输入量
            long tIn = Long.parseLong(dayList.get(0).getInFlow( ));
            dIn = countCurrentFlowTrend(cIn, tIn);
        }
        String cOutStr = NumConversion.conversionNumUnit(cOut) + "条";
        String cInStr = NumConversion.conversionNumUnit(cIn) + "条";
        List<Map<String, Object>> ret = Lists.newArrayList( );
        //封装读取
        Map<String, Object> singleStat = new HashMap<>( );
        singleStat.put("state", dOut);
        singleStat.put("num", cOutStr);
        ret.add(singleStat);
        //封装写入
        singleStat = new HashMap<>( );
        singleStat.put("state", dIn);
        singleStat.put("num", cInStr);
        ret.add(singleStat);
        return ret;
    }

    /**
     * 默认为1就上升,0是下降
     *
     * @param currentNum 当前数量
     * @param totalNum   总量
     * @return
     */
    private int countCurrentFlowTrend(long currentNum, long totalNum) {
        long hourNum = 30 * 24;//三十天总共的小时数量
        long avgNum = totalNum / hourNum;
        LocalDateTime today = LocalDateTime.now( );
        int currentHour = today.getHour( );
        if (currentHour == 0) {
            currentHour = 1;
        }
        //当前平均量数据
        long curAvg = avgNum * currentHour;
        int dir = currentNum >= curAvg ? 1 : 0;
        return dir;
    }

    @Override
    public List<ResourceRiskEventVo> findNewlyRiskEvent() {
      String currentDate=  DateUtil.getTodayShortDateFormat();
        return resourceStatMapper.findNewlyRiskEvent(currentDate);
    }
}
